package com.iot08.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iot08.api.config.redis.RedisClusterService;
import com.iot08.api.service.AccountService;
import com.iot08.api.service.WxVipCnsService;
import com.iot08.api.service.WxgzConfigService;
import com.iot08.api.service.supplement.WeixinService;
import com.iot08.api.service.supplement.WxWebApiService;
import com.iot08.api.utils.buckettool.BaseBucketTool;
import com.iot08.api.vo.request.*;
import com.iot08.common.constant.CacheEnum;
import com.iot08.common.entity.app.Account;
import com.iot08.common.entity.app.Wxgzconfig;
import com.iot08.common.utils.HttpReq;
import com.iot08.common.utils.StringUtil;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.conn.EofSensorInputStream;
import org.apache.http.message.BasicHeader;
import org.apache.kafka.common.protocol.types.Field;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 赛诺的公众号配置
 *
 * @version 1.0
 * @time: 4/8/22 5:55 PM
 * @author: Weichao
 */
@Slf4j
@RestController
@RequestMapping("getway")
public class WxSmallProgramApiController {
    @Resource
    private WeixinService weixinService;

    @Resource
    private WxgzConfigService wxgzConfigService;

    @Resource
    private AccountService accountService;

    @Resource
    private BaseBucketTool baseBucketTool;

    @Value("${wxSmallProgram.jsonArrPageUrl:[\"pages/dictionary/device/bindDevice\"]}")
    private String jsonArrPageUrl;


    /**
     * 微信小程序-获取手机号
     */
    @PostMapping("wxSmallProgram/getWxUserPhoneNumber")
    public ResponseMap getWxUserPhoneNumber(@Validated WXSmallProgramReqVO vo) throws IOException {
        try {
            //传入小程序的原始ID
            String accessToken = weixinService.getAccessToken(vo.getOriginalId());
            String phone = getWxUserInfoPhone(vo.getCode(), accessToken);
            //更新对用的用户信息的手机号
            Update update = new Update();
            update.set("phone", phone);
            accountService.updateById(vo.getOpenid(), update);
            log.info("微信小程序-获取手机号 同时更新此用户的手机号 vo = {} phone:{}", vo, phone);
            JSONObject res = new JSONObject();
            res.put("phone", phone);
            return ResponseMap.success(res);
        }catch (Exception e){
            log.error(" 微信小程序-获取手机号 :"+e.getMessage(), e);
            return ResponseMap.fail();
        }

    }

    @PostMapping("wxSmallProgram/getWxSmallProgramUnionid")
    public ResponseMap getWxSmallProgramUnionid(WXSmallProgramReqVO vo){
        try {
            Wxgzconfig wxgzconfig = wxgzConfigService.findById(vo.getOriginalId());
            if (wxgzconfig != null) {
                String appId = wxgzconfig.getAppid();
                String appSecret = wxgzconfig.getAppsecret();
                JSONObject res = new JSONObject();
                JSONObject jsonResponse = getWxSmallProgramUnionid(appId, appSecret, vo.getCode());
                String unionid = jsonResponse.getString("unionid");
//                String sessionKey = jsonResponse.getString("session_key");
                String openid = jsonResponse.getString("openid");
                res.put("unionid", unionid);
//                res.put("session_key", sessionKey);
                res.put("openid", openid);
                return ResponseMap.success(res);
            }else{
                return ResponseMap.fail("找不到对应配置");
            }
        }catch (Exception e){
            log.error(" 获取小程序 用户unionid :"+e.getMessage(), e);
        }
        return ResponseMap.fail();

    }

    /**
     * 获取小程序手机号
     *
     * @param auth_code
     * @param accessToken
     * @return
     * @throws IOException
     */
    public static String getWxUserInfoPhone(String auth_code, String accessToken) throws IOException {
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?" + "access_token=" + accessToken;

        JSONObject params = new JSONObject();
        params.put("code", auth_code);
        String data = HttpReq.sendPostJson(url, params.toJSONString());
        log.info("获取小程序的手机号返回结果:{}", data);
        JSONObject jsonResponse = JSONObject.parseObject(data);
        String purePhoneNumber = jsonResponse.getJSONObject("phone_info").getString("purePhoneNumber");
        return purePhoneNumber;
    }


    /**
     * 获取小程序 用户unionid
     * @param appid
     * @param appSecret
     * @param js_code
     * @return
     * @throws IOException
     */
    public static JSONObject getWxSmallProgramUnionid(String appid, String appSecret, String js_code) throws IOException {
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",appid, appSecret,js_code);
        String data = HttpReq.sendGet(url);
        log.info("获取小程序 用户unionid 返回结果:{}", data);
        JSONObject jsonResponse = JSONObject.parseObject(data);
        return jsonResponse;
    }



    @PostMapping("wxSmallProgram/getwxacodeunlimit")
    public ResponseMap getwxacodeunlimit(WXSmallProgramReqVO vo){
        //检查OSS上是否已经存有,有则返回,无则直接返回
        String filePath = String.format("%s%s/%s/%s",
                BaseBucketTool.WXSMALLPROGRAM_COMPLAINT_PATH,
                "dispen",
                vo.getOriginalId(),
                vo.getImei()+vo.getOriginalId()+"-"+vo.getEnvType()+".png");
        JSONObject res = new JSONObject();
        boolean isExist = baseBucketTool.checkPath(filePath);
        if(isExist){
            res.put("url", baseBucketTool.getDOMAIN() + filePath);
            return ResponseMap.success(res);
        }

        JSONArray pageUrlArr = JSONArray.parseArray(jsonArrPageUrl);
        String pageUrl = pageUrlArr.getString(0);
        if (vo.getPageUrlType() < pageUrlArr.size()){
            pageUrl = pageUrlArr.getString(vo.getPageUrlType());
        }
        if (StringUtils.isEmpty(vo.getImei())) {
            return ResponseMap.fail("miss imei");
        }

        InputStream wxMiniQrCode = getWxMiniQrCode(weixinService.getAccessToken(vo.getOriginalId()), vo.getImei(), pageUrl, vo.getEnvType(), vo.getWidth());
        if (wxMiniQrCode == null) {
            return ResponseMap.fail("获取异常,请检查参数");
        }
        try {
            //保存到 OSS上 并给个URL
            baseBucketTool.upload(filePath, wxMiniQrCode, 4);
            res.put("url", baseBucketTool.getDOMAIN() + filePath);
            return ResponseMap.success(res);
        } catch (Exception e) {
            log.error("二维码保存到OSS上错误:" + e.getMessage(), e);
            return ResponseMap.fail("生成失败");
        }
    }

    /**
     * 通过该接口生成的小程序码，永久有效，数量暂无限制
     * @param accessToken
     * @param scene
     * @param pageUrl
     * @return
     */
    //https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
    public static InputStream getWxMiniQrCode(String accessToken, String scene, String pageUrl, int env, int width){
        String requestUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
        Map<String, Object> requestParam = new HashMap<>();
        String env_version = "develop";
        switch (env){
            case 0:
                env_version = "release";
                break;
            case 1:
                env_version = "trial";
                break;
            case 2:
                env_version = "develop";
                break;
        }
        //env_version 要打开的小程序版本。正式版为 "release"，体验版为 "trial"，开发版为 "develop"。默认是正式版。
        requestParam.put("env_version", env_version);
        //默认是true，检查page 是否存在，为 true 时 page 必须是已经发布的小程序存在的页面（否则报错）；为 false 时允许小程序未发布或者 page 不存在， 但page 有数量上限（60000个）请勿滥用。
        requestParam.put("check_path", false);
        requestParam.put("scene", scene);               //最大32个可见字符，只支持数字，大小写英文以及部分特殊字符
        requestParam.put("page", pageUrl);             //必须是已经发布的小程序存在的页面（否则报错）
        requestParam.put("width", width);                //二维码的宽度，单位 px，最小 280px，最大 1280px 默认 430
        requestParam.put("auto_color", false);         //自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调，默认 false
        // requestParam.put("line_color", "");         //auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
        requestParam.put("is_hyaline", false);          //是否需要透明底色，为 true 时，生成透明底色的小程序

        byte[] codeData = HttpReq.sendPostReturnInputStream(requestUrl, JSONObject.toJSONString(requestParam), null);
        if (codeData == null){
            return null;
        }
        //JPG 转 PNG
        return jpeg2png(new ByteArrayInputStream(codeData));
    }


    public static InputStream jpeg2png(InputStream inputStream) {
        //读取图片
        try {
            BufferedImage bufferedImage = ImageIO.read(inputStream);
            //转成png、
            BufferedImage bufferedImage1 = new BufferedImage(bufferedImage.getWidth(),
                    bufferedImage.getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
            bufferedImage1.createGraphics().drawImage(bufferedImage,0,0, Color.white,null);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage1, "png", os);
            return new ByteArrayInputStream(os.toByteArray());
        } catch (IOException e) {
            log.error("小程序码JPEG图片 转换 成PNG图片错误 "+e.getMessage(), e);
        }
        return null;
    }

    public static void main(String[] args) {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", "wxe8eaa058adc26a72", "5c646483144be3a05e37fc06d326b77f");
        String data = HttpReq.sendGet(url, null);
        System.out.println("data:"+data);
        //data:{"access_token":"75_AhcVIUHP29a5Kyhd0fM8vAN5J8ghrBnO2dd3f4y8HwIObQGDb1K1Khy8OZ5BDglvV6hZW5NBwWhCh0hG2GHY4qVuZfya6lWTdh4mvcyRS8KEJgeNAtMErlq9lUYCHZaACAHME","expires_in":7200}


    }

}
